//
//  HLUniversalFunc.swift
//  HLDesktop
//
//  Created by 子凡 on 2025/4/10.
//


import UIKit

//项目专用-公共方法
let prjTitleColor = UIColor("#1296db")
let defaultIcoLogo = "app_default@2x.png"
let albumGifDataKey = "aiScreen.pCache.album.gif"

class HLUniversalFunc:NSObject{
//单例初始化方法1：
    static let sharedInstance = HLUniversalFunc() //单例
    
////单例初始化方法2(此方法，可以将单例销毁)：
//    private static var _sharedInstance:HLUniversalFunc?
//    class func getInstance()->HLUniversalFunc{
//        guard let instance = _sharedInstance else{
//            _sharedInstance = HLUniversalFunc()
//            return _sharedInstance!
//        }
//        return instance
//    }
////销毁单例
//    class func destory(){
//        _sharedInstance = nil
//    }
    
//私有化init方法
    private override init(){
//重写init，用来保证init方法的私有性，这样才能保证单例是真正唯一的，避免外部对象通过访问init方法创建单例类的其他实例。
//这样做就可以保证编译器在某个类尝试使用()来初始化HLUniversalFunc时，抛出错误
//eg: let tmpfunc = HLUniversalFunc()
//会报错: 'HLUniversalFunc' initializer is inaccessible due to 'private' protection level
        super.init()
    }
    
}

extension HLUniversalFunc{
    //--------------------常用类func
    //MARK: - 取2个浮点数区间
    class func randomFloatBetween(_ smallNumber: CGFloat, and bigNumber: CGFloat) -> Float {
        let diff = bigNumber - smallNumber
        return Float((CGFloat(arc4random()) / 100.0).truncatingRemainder(dividingBy: diff) + smallNumber)
    }
    
    //MARK: - openscheme
    class func openAppScheme(_ schemeurl:String,_ completeblock: ((_ success:Bool)->Void)?){
        if 0 == schemeurl.count{
            if completeblock != nil{
                completeblock?(false)
            }
            return
        }
        if schemeurl.hasPrefix("hl://scheme2?u="){
            let strbid = (schemeurl as NSString).substring(from: "hl://scheme2?u=".count) as String
            if strbid.count>0{
                let flag = openBundleID(strbid)
                if completeblock != nil{
                    completeblock?(flag)
                }
                return
            }
        }
    //判断带有://则为urlScheme，其它则为open-bid处理
        if schemeurl.contains("://") || schemeurl.hasPrefix("App-Prefs:"){//urlscheme及设置
            openSchemeUrl(schemeurl, completeblock)
        }else{
    //当成bid处理
            let flag = openBundleID(schemeurl)
            if !flag {
                openSchemeUrl(schemeurl, completeblock) //再尝试一下scheme打开
            }else if completeblock != nil{
                completeblock?(flag)
            }
        }
    }

    class func openSchemeUrl(_ schemeurl:String,_ completeblock: ((_ success:Bool)->Void)?){
        if let url = NSURL(string: schemeurl){
    //if UIApplication.shared.canOpenURL(url! as URL){
    //判断能否打开必须在Queried URL Schemes里包含对应的scheme，才能准确判断
    //但即使不包含的话，也可以openUrl成功，故弃用判断
            UIApplication.shared.open(url as URL,options: [:]) { success in
                if success {
                    if completeblock != nil{
                        completeblock?(true)
                    }
                }else{
                    NSLog("打开取消或失败:\(schemeurl)")
                    if completeblock != nil{
                        completeblock?(false)
                    }
                }
            }
        }
    }

    //open-bid
    class func openBundleID(_ bundleID:String) -> Bool{
        if bundleID.isEmpty{
            return false
        }
        let clstr = "TFNBcHBsaWNhdGlvbldvcmtzcGFjZQ".base64DecodeStr()
        let prostr = "b3BlbkFwcGxpY2F0aW9uV2l0aEJ1bmRsZUlEOg".base64DecodeStr()
        if clstr != nil && prostr != nil{
           return OCFunc.showNextBundle(with:clstr! , andPeform:prostr! , andTitle: bundleID)
        }else{
            return false
        }
    }
    
    //MARK: - 读取本地json文件中的Array数据
    class func getArrFromJSONFile(forName name: String) -> Array<String> {
        if name.isEmpty{
            return []
        }
       do {
          if let bundlePath = Bundle.main.path(forResource: name, ofType: "json"),
          let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8) {
             if let json = try JSONSerialization.jsonObject(with: jsonData, options: .mutableLeaves) as? [String] {
    //            print("JSON: \(json)")
                 return json
             } else {
                print("Given JSON is not a valid dictionary object.")
             }
          }
       } catch {
          print(error)
       }
        return []
    }
    
// debug下日志打印封装
    func HL_Log<T>(_ message : T) {
        
        #if DEBUG
            print("\(message)")
        #endif
    }
    
    /// 打印内容，并包含类名和打印所在行数
    ///
    /// - Parameters:
    ///   - message: 打印消息
    ///   - file: 打印所属类
    ///   - lineNumber: 打印语句所在行数
    class func HL_LogLine<T>(message : T, file : String = #file, lineNumber : Int = #line) {
        #if DEBUG
            let fileName = (file as NSString).lastPathComponent
            print("[\(fileName)<\(lineNumber)>]- \(message)")
        #endif
    }
}

extension HLUniversalFunc{
//------------------常用单例func
    //MARK: - 获取App缓存大小、删除缓存
    func fileSizeOfCache()-> Float {    // 取出cache文件夹目录 缓存文件都在这个目录下
        let cachePath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.cachesDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
        //缓存目录路径 "/var/mobile/Containers/Data/Application/5AB973F7-5767-4811-B95B-920E2593F108/Library/Caches"
        //取出文件夹下所有文件数组
        let fileArr = FileManager.default.subpaths(atPath: cachePath!)    //快速枚举出所有文件名 计算文件大小
        var size = 0
        for file in fileArr! {        // 把文件名拼接到路径中
            let path = cachePath?.appending("/\(file)")//"/var/mobile/Containers/Data/Application/5AB973F7-5767-4811-B95B-920E2593F108/Library/Caches/com.apple.dyld"
            // 取出文件属性
            let floder = try! FileManager.default.attributesOfItem(atPath: path!)
            // 用元组取出文件大小属性
            for (abc, bcd) in floder {
                // 累加文件大小
                if abc == FileAttributeKey.size {
                    size += (bcd as AnyObject).integerValue
                }
            }
        }
        let mm = Double(size) / 1024.0 / 1024.0
        return Float(mm)
    }
    
    func fileSizeOfUserData()->Float{
        let userDefaults = UserDefaults.standard
        let dics = userDefaults.dictionaryRepresentation()
    //    print("UserDefaults.count = \(dics.count)")
        var result = 0.0
        for key in dics {
            let keyName = key.key //包含系统为App配置的一些默认参数，故只需删除自身需要删除的即可
            print("calc.key:\(key.key)")
            if keyName.hasPrefix("aiScreen.pCache."){
                if let data = key.value as? Data{
                    let iSize = Double(data.count) / 1000000.0
                    result = result + iSize
                    print("calc.size: \(iSize)M")
                }
            }
        }//清除所有可能的图片缓存(所有可以清除的缓存(如图片缓存)等都以aiScreen.开头)
        return Float(result)
    }
    
    func fileSizeOfAllCache()->Float{
        let cachSize = fileSizeOfCache()
        let userSize = fileSizeOfUserData()
        return cachSize + userSize
    }
    
    func clearCache() {    // 取出cache文件夹目录 缓存文件都在这个目录下
        let cachePath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.cachesDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first    // 取出文件夹下所有文件数组
        let fileArr = FileManager.default.subpaths(atPath: cachePath!)    // 遍历删除
        for file in fileArr! {
            let path = cachePath?.appending("/\(file)")
            if FileManager.default.fileExists(atPath: path!) {
                do {
                try FileManager.default.removeItem(atPath: path!)
                }
                catch {
                    print("clearCache.err")
                }
            }
        }
    }
    
    func clearUserDefaultsData(deepClean:Bool=false){
       let userDefaults = UserDefaults.standard
       let dics = userDefaults.dictionaryRepresentation()
    //    print("UserDefaults.count = \(dics.count)")
       for key in dics {
           let keyName = key.key //包含系统为App配置的一些默认参数，故只需删除自身需要删除的即可
           if keyName.hasPrefix("aiScreen.App.page") || keyName.hasPrefix("aiScreen.Agreed."){
               //深度清理也不能把App配置 或 协议配置清掉,
               print("cancel.key:\(key.key)")
           }else if deepClean || keyName.hasPrefix("aiScreen.pCache.") || keyName.hasPrefix("aiScreen.dCache."){
               print("remove.key:\(key.key)")
               userDefaults.removeObject(forKey: key.key)
           }else{
               print("cancel.otherkey:\(key.key)")
           }
       }//清除所有可能的图片缓存(所有可以清除的缓存(如图片缓存)等都以aiScreen.开头)
       userDefaults.synchronize()
    }
    
    func clearAllCache(deepClean:Bool=false){
        clearCache()
        clearUserDefaultsData(deepClean: deepClean)
    }
}

